package com.ygqh.baby.redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Transaction;

import java.util.List;
import java.util.Set;

public class RedisDao {

    private JedisSentinelPool jedisPool;

    /**
     * 监控key
     */
    public void watch(String keys) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.watch(keys);
        } finally {
            jedis.close();
        }
    }

    /**
     * 开启事务
     */
    public Transaction multi() {
        Jedis jedis = jedisPool.getResource();
        Transaction tx = null;
        try {
            tx = jedis.multi();
        } finally {
            jedis.close();
        }
        return tx;
    }

    /**
     * get value from redis
     *
     * @param key
     * @return
     */
    public byte[] get(byte[] key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.get(key);
        }
    }

    /**
     * set
     *
     * @param key
     * @param value
     * @return
     */
    public byte[] set(byte[] key, byte[] value) {
        Jedis jedis = jedisPool.getResource();

        try {
            jedis.set(key, value);
        } finally {
            jedis.close();
        }
        return value;
    }

    /**
     * set 字符串
     *
     * @param key
     * @param value
     * @return
     */
    public String set(String key, String value, int expire) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.set(key, value);
            if (expire != 0) {
                jedis.expire(key, (expire / 1000));
            }
        } finally {
            jedis.close();
        }
        return value;
    }

    /**
     * 注意：有效期为long值是传的失效日期的时间戳
     *
     * @param key
     * @param value
     * @param unixTime
     * @return String    返回类型
     * @throws
     * @Title: set
     * @author （guohao）
     * @date 2018年6月5日 下午5:01:15
     * @version V1.0
     */
    public String set(String key, String value, long unixTime) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.set(key, value);
            if (unixTime != 0) {
                jedis.expireAt(key, (unixTime / 1000));
            }
        } finally {
            jedis.close();
        }
        return value;
    }

    public byte[] set(byte[] key, byte[] value, long unixTime) {
        Jedis jedis = jedisPool.getResource();
        try {
            String set = jedis.set(key, value);
            System.out.println(set);
            if (unixTime != 0) {
                Long expireAt = jedis.expireAt(key, (unixTime / 1000));
                System.err.println(expireAt);
            }
        } finally {
            jedis.close();
        }
        return value;
    }

    public String hget(String key, String field) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.hget(key, field);
        }
    }

    public List<String> hget(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.hvals(key);
        }
    }

    public Long hdel(String key, String... fields) {
        Jedis jedis = jedisPool.getResource();
        Long hdel;
        try {
            hdel = jedis.hdel(key, fields);
        } finally {
            jedis.close();
        }
        return hdel;
    }

    public Long hset(String key, String field, String value) {
        Jedis jedis = jedisPool.getResource();
        Long hset;
        try {
            hset = jedis.hset(key, field, value);
        } finally {
            jedis.close();
        }
        return hset;
    }

    public void hset(String key, String field, String value, long timestamp) {
        Jedis jedis = jedisPool.getResource();
        try {
            Pipeline p = jedis.pipelined();
            p.hset(key, field, value);
            p.expireAt(key, timestamp);
            p.sync();
        } finally {
            jedis.close();
        }
    }

    public void hset(byte[] key, byte[] field, byte[] value, int seconds) {
        Jedis jedis = jedisPool.getResource();
        Pipeline p = jedis.pipelined();
        p.hset(key, field, value);
        p.expire(key, seconds);
        p.sync();
        jedis.close();

    }

    public void hset(byte[] key, byte[] field, byte[] value, Long timestamp) {
        Jedis jedis = jedisPool.getResource();
        Pipeline p = jedis.pipelined();
        p.hset(key, field, value);
        p.expireAt(key, timestamp);
        p.sync();
        jedis.close();

    }


    public List<String> hmget(String key, String... field) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.hmget(key, field);
        }
    }

    /**
     * set 字符串
     */
    public String get(String key) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.get(key);
        }
    }

    /**
     * set
     *
     * @param key
     * @param value
     * @param expire
     * @return
     */
    public byte[] set(byte[] key, byte[] value, int expire) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.set(key, value);
            if (expire != 0) {
                jedis.expire(key, (expire / 1000));
            }
        } finally {
            jedis.close();
        }
        return value;
    }

    /**
     * del
     *
     * @param key
     */
    public void del(byte[] key) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.del(key);
        } finally {
            jedis.close();
        }
    }

    public void del(String... key) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.del(key);
        } finally {
            jedis.close();
        }
    }

    /**
     * Redis SREM命令用于从所述一组保存在键中删除指定的元素。如果成员不存在，则命令返回0，如果没有设置在关键存储的值，则返回一个错误。
     *
     * @param keys
     * @param key  入参
     * @return void    返回类型
     * @throws
     * @Title: srem
     * @author （guohao）
     * @date 2018年6月28日 下午2:17:48
     * @version V1.0
     */
    public void srem(String keys, String key) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.srem(keys, key);
        } finally {
            jedis.close();
        }
    }

    /**
     * Redis SADD命令用于添加成员设置保存在key。如果成员已经存在，那么它忽略。如果键不存在，那么新的集合创建和成员被添加进去。如果没有设置储存在键的值，则返回一个错误。
     *
     * @param keys
     * @param key  入参
     * @return void    返回类型
     * @throws
     * @Title: sadd
     * @author （guohao）
     * @date 2018年6月28日 下午2:18:54
     * @version V1.0
     */
    public void sadd(String keys, String key) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.sadd(keys, key);
        } finally {
            jedis.close();
        }
    }

    /**
     * flush
     */
    public void flushDB() {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.flushDB();
        } finally {
            jedis.close();
        }
    }

    /**
     * size
     */
    public Long dbSize() {
        Long dbSize = 0L;
        Jedis jedis = jedisPool.getResource();
        try {
            dbSize = jedis.dbSize();
        } finally {
            jedis.close();
        }
        return dbSize;
    }

    /**
     * keys
     */
    public Set<byte[]> keys(String pattern) {
        Set<byte[]> keys = null;
        Jedis jedis = jedisPool.getResource();
        try {
            keys = jedis.keys(pattern.getBytes());
        } finally {
            jedis.close();
        }
        return keys;
    }

    public JedisSentinelPool getJedisPool() {
        return jedisPool;
    }

    public void setJedisPool(JedisSentinelPool jedisPool) {
        this.jedisPool = jedisPool;
    }
}
